package com.bingxue.edu.common.util;

import cn.hutool.core.util.RandomUtil;
import com.bingxue.edu.common.enums.ClassStatusEnum;
import com.bingxue.edu.common.enums.TermEnum;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.framework.exception.BusinessException;
import com.bingxue.edu.management.education.model.entity.ClassInfo;
import com.bingxue.edu.management.education.model.entity.Enrollment;
import com.bingxue.edu.management.education.model.req.ClassInfoCreateReq;

import java.time.LocalDateTime;

import static cn.hutool.core.date.DatePattern.PURE_DATETIME_MS_FORMATTER;

/**
 * @author panbo
 * @since 2024/11/6
 */
public class EduUtil {

    /**
     * 生成班级id
     */
    public static String generateClassId(ClassInfoCreateReq req) {
        Integer classYear = req.getClassYear();
        TermEnum term = req.getTerm();
        String randomString = RandomUtil.randomNumbers(6);
        return String.format("%s%s%s", classYear, term.getCode(), randomString);
    }

    /**
     * 生成订单编号
     * 共20位：yyyyMMddHHmmssSSS + 3位随机数
     */
    public static String generateOrderId() {
        return LocalDateTime.now().format(PURE_DATETIME_MS_FORMATTER) + RandomUtil.randomNumbers(3);
    }

    /**
     * 生成退款单编号
     * 共20位：yyyyMMddHHmmssSSS + 3位随机数
     */
    public static String generateRefundId() {
        return LocalDateTime.now().format(PURE_DATETIME_MS_FORMATTER) + RandomUtil.randomNumbers(3);
    }

    /**
     * 获取当前班级前一期所在学期
     */
    public static TermEnum getPrevClassTerm(ClassInfo currentClassInfo) {
        TermEnum currentTerm = currentClassInfo.getTerm();
        int currentTermIndex = currentTerm.getIndex();
        int prevTermIndex = currentTermIndex - 1;
        if (prevTermIndex == 0) {
            prevTermIndex = 4;
        }
        return TermEnum.getByIndex(prevTermIndex);
    }

    /**
     * 获取当前班级前一期所在学年
     * 每年从寒假开始 寒-春-暑-秋
     */
    public static Integer getPrevClassYear(ClassInfo currentClassInfo) {
        Integer year = currentClassInfo.getClassYear();
        TermEnum currentTerm = currentClassInfo.getTerm();
        if (currentTerm == TermEnum.WINTER) {
            year -= 1;
        }
        return year;
    }

    /**
     * 获取当前班级下一期所在学期
     */
    public static TermEnum getNextClassTerm(ClassInfo currentClassInfo) {
        TermEnum currentTerm = currentClassInfo.getTerm();
        int currentTermIndex = currentTerm.getIndex();
        int prevTermIndex = currentTermIndex + 1;
        if (prevTermIndex == 5) {
            prevTermIndex = 1;
        }
        return TermEnum.getByIndex(prevTermIndex);
    }

    /**
     * 获取当前班级下一期所在学年
     * 每年从寒假开始 寒-春-暑-秋
     */
    public static Integer getNextClassYear(ClassInfo currentClassInfo) {
        Integer year = currentClassInfo.getClassYear();
        TermEnum currentTerm = currentClassInfo.getTerm();
        if (currentTerm == TermEnum.AUTUMN) {
            year += 1;
        }
        return year;
    }

    /**
     * 校验班级状态
     */
    public static void checkClassStatus(ClassInfo classInfo) {
        ValidationUtils.throwIf(ClassStatusEnum.COMPLETED == classInfo.getClassStatus() || ClassStatusEnum.CLOSED == classInfo.getClassStatus()
                , "班级[{}]{}", classInfo.getName(), classInfo.getClassStatus().getLabel());
    }

    /**
     * 校验班级可用名额
     */
    public static void checkAvailableCount(ClassInfo classInfo) {
        int availableCount = classInfo.getPlanStudentCount() - classInfo.getEnrollStudentCount();
        ValidationUtils.throwIf(availableCount <= 0, "班级人数已满");
    }

    /**
     * 判断报名时间是否满足要求，3阶段规则
     */
    public static void checkEnrollTime(ClassInfo classInfo) {
        LocalDateTime now = LocalDateTime.now();
        // 设置了续报开始时间，且当前时间在续报期内，允许报名
        if (classInfo.getRenewalStartTime() != null && classInfo.getRenewalEndTime() != null) {
            if(now.isAfter(classInfo.getRenewalStartTime()) && now.isBefore(classInfo.getRenewalEndTime())) {
                return;
            }
        }
        // 否则需要在开放报名时间之后才允许报名
        if (classInfo.getEnrollStartTime() != null && now.isBefore(classInfo.getEnrollStartTime())) {
            throw new BusinessException("报名时间未开始");
        }
    }

    /**
     * 转班调课时间判断
     */
    public static void checkChangeTime(ClassInfo oldClass, ClassInfo newClass) {
        LocalDateTime now = LocalDateTime.now();
        if (oldClass.getRenewalEndTime() != null && now.isBefore(oldClass.getRenewalEndTime())) {
            throw new BusinessException("当前时间不允许转班调课");
        }
        if (newClass.getRenewalEndTime() != null && now.isBefore(newClass.getRenewalEndTime())) {
            throw new BusinessException("当前时间不允许转班调课");
        }
    }

    /**
     * 校验剩余转班次数
     */
    public static void checkClassChangeRemainCount(Enrollment enrollment) {
        ValidationUtils.throwIfNull(enrollment, "未查询到报名信息");
        ValidationUtils.throwIf(enrollment.getRemainClassChangeCount() == 0, "转班次数不足");
    }

    /**
     * 校验剩余调课次数
     */
    public static void checkLessonChangeRemainCount(Enrollment enrollment) {
        ValidationUtils.throwIfNull(enrollment, "未查询到报名信息");
        ValidationUtils.throwIf(enrollment.getRemainLessonChangeCount() == 0, "调课次数不足");
    }
}
